﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DoKnow.CloudEdu.CMS.Host.Models;
using DoKnow.CloudEdu.Common.Attrs;
using DoKnow.CloudEdu.Common.Consts;
using DoKnow.CloudEdu.Common.Enums;
using DoKnow.CloudEdu.DataContract.Model.Base;

namespace DoKnow.CloudEdu.CMS.Host.Controllers
{
    public class BaseController : Controller
    {
        public static readonly string Request_Path_Item_Key = "RequestPath";
        public static readonly string Menu_Path_Item_Key = "MenuPath";
        //private UserWrapper _user;
        public UserData CurrentUser
        {
            get
            {
                return CurSession.User;
            }
        }

        public string  Server
        {
            get
            {
                return CurCache.ServiceHost;
            }
        }

        //public static readonly int PageSize = ConfigurationManager.AppSettings["PageSize"] == null ? 20 : Int32.Parse(ConfigurationManager.AppSettings["PageSize"]);

        private int _invoke_count { get; set; }
        private string _loginToken { get; set; }
        public string LoginToken { get { return _loginToken; } }
        public List<SelectListItem> GetSelectList<T>()
        {
            List<SelectListItem> statusList = new List<SelectListItem>();
            statusList.Add(new SelectListItem() { Value = "0", Text = "全部" });
            SortedList statusEnums = EnumHelper.GetStatus(typeof(T));
            foreach (object key in statusEnums.Keys)
            {
                statusList.Add(new SelectListItem() { Value = key.ToString(), Text = statusEnums[key].ToString() });
            }
            return statusList;
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="ExpList"></param>
        /// <param name="BodySizeList">净体尺码</param>
        /// <param name="clotheSizeList">成衣尺码</param>
        //public void WriteExcelToReponse<T>(List<T> ExpList, string tempalteFile, int startRow, int startColumn)
        //{
        //    ExcelReportWriter<T> report = new ExcelReportWriter<T>(tempalteFile, startRow, startColumn);
        //    report.Fill(ExpList);

        //    string ExcelName = HttpUtility.UrlEncode(DateTime.Now.ToString("yyyy-MM-dd"), Encoding.UTF8) + tempalteFile;
        //    Response.Clear();
        //    Response.ClearHeaders();
        //    Response.ClearContent();
        //    Response.Buffer = false;
        //    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        //    Response.ContentEncoding = Encoding.GetEncoding("UTF-8");
        //    Response.AppendHeader("Content-Disposition", "Attachment;filename=" + ExcelName);
        //    report.Write(Response.OutputStream);
        //    Response.Flush();
        //    Response.End();
        //}

        #region Session
        public void AddSession<T>(string key, T value)
        {
            Session[key] = value;
        }
        public T GetSession<T>(string key) where T : class
        {
            return Session[key] as T;
        }
        #endregion Session
        private NameValueCollection GetCurrentRequestParam()
        {
            string area = string.Empty, controller = string.Empty, action = string.Empty;
            if (ControllerContext.IsChildAction)
            {
                var parentContext = ControllerContext.ParentActionViewContext as System.Web.Mvc.ControllerContext;
                controller = parentContext.RequestContext.RouteData.Values["controller"].ToString().ToLower();
                action = parentContext.RequestContext.RouteData.Values["action"].ToString().ToLower();
                if (parentContext.RouteData.DataTokens["area"] != null)
                {
                    area = parentContext.RouteData.DataTokens["area"].ToString().ToLower();
                }
            }
            else
            {
                if (ControllerContext.RouteData.DataTokens["area"] != null)
                {
                    area = ControllerContext.RouteData.DataTokens["area"].ToString().ToLower();
                }

                controller = ControllerContext.RequestContext.RouteData.Values["controller"].ToString().ToLower();
                action = ControllerContext.RequestContext.RouteData.Values["action"].ToString().ToLower();
            }
            return new NameValueCollection() { { "AREA", area }, { "CONTROLLER", controller }, { "ACTION", action } };
        }

        /// <summary>
        /// 在进行授权时调用
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void OnAuthorization(AuthorizationContext filterContext)
        {

            var menuItemAttr = filterContext.ActionDescriptor.GetCustomAttributes(typeof(MenuItemAttribute), true);
            if (menuItemAttr.Count() > 0)
            {
                string menuItemPath = (menuItemAttr[0] as MenuItemAttribute).Path;
                if (!string.IsNullOrEmpty(menuItemPath))
                {
                    filterContext.HttpContext.Items[Menu_Path_Item_Key] = menuItemPath.Trim('~').ToLower();
                }
            }

            var requestParam = GetCurrentRequestParam();

            var requestPath = string.Join("/", requestParam["AREA"], requestParam["CONTROLLER"], requestParam["ACTION"]).ToLower();

            filterContext.HttpContext.Items[Request_Path_Item_Key] = requestPath;
            /*
            if (filterContext.IsChildAction)
            {
                base.OnAuthorization(filterContext);
                return;
            }

            HttpContext.User = this.User;

            
            if (FormsAuthenticationService.LoginUrl.Trim('~').ToLower().StartsWith(requestPath))
            {
                base.OnAuthorization(filterContext);
            }
            else if (HttpContext.User.Identity.IsAuthenticated)
            {
                if ((HttpContext.Request).HttpMethod == "GET")
                {
                    LogHelper.Info(this.GetType(), UserSession.Current.UserCode + " visit:" + requestPath);
                }

                //if (UserSession.Current.CheckPagePermit(permitCode))
                //{
                base.OnAuthorization(filterContext);
                //}
            }
            else
            {
                var loginUrl = string.Format("{0}?redirectUrl={1}", FormsAuthenticationService.LoginUrl, HttpUtility.UrlEncode(base.Request.Url.AbsoluteUri));
                base.Response.Redirect(loginUrl, true);
            }
             */
        }

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.ActionDescriptor.ActionName != "Login")
            {
                
                HttpCookie authCookie = Request.Cookies[CookiesKey.LoginToken];
                if (authCookie == null || string.IsNullOrEmpty(authCookie.Value))
                {
                    filterContext.Result = RedirectToAction("Login", "Home");
                }
                else
                {
                    _loginToken = authCookie.Value; 
                    if (CurrentUser == null)
                    {
                        filterContext.Result = RedirectToAction("Login", "Home");
                    }
                    else if (!filterContext.IsChildAction)
                    {
                        var module = CurCache.BSModuleFull.Find(i => i.ModuleCode.Equals(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, StringComparison.CurrentCultureIgnoreCase));
                        if (module == null)
                        {
                            filterContext.Result = RedirectToAction("Login", "Home");
                        }
                        else
                        {
                            var roleIds = CurrentUser.UserRoles.Select(i => i.RoleID).Distinct();
                            var moduleIds = CurCache.BSRoleModuleFull.Where(o => roleIds.Contains(o.RoleID)).Select(o => o.ModuleID).Distinct();
                            var modules = CurCache.BSModuleFull.Where(o => moduleIds.Contains(o.ID)).ToList();
                            var parentModuleIds = modules.Select(o => o.ParentID).Distinct();
                            modules = CurCache.BSModuleFull.Where(i => parentModuleIds.Contains(i.ID)).Concat(modules).ToList();
                            if (!modules.Exists(i => i.ID == module.ID))
                            {
                                filterContext.Result = RedirectToAction("Login", "Home");
                            }
                        }
                    }
                }
            }
        }
    }
}
